Skip to content

test(SDK-615): inbox message display URL handling - #940

Open
jferrao-itrbl wants to merge 3 commits into
masterfrom
feature/SDK-615-tests-for-IterableInboxMessageDisplay
Open

jferrao-itrbl wants to merge 3 commits into
masterfrom
feature/SDK-615-tests-for-IterableInboxMessageDisplay

Conversation

@jferrao-itrbl

@jferrao-itrbl jferrao-itrbl commented Nov 6, 2026 •

Copy link
Copy Markdown
Collaborator

📝 Summary

Adds Jest coverage for IterableInboxMessageDisplay link routing and fixes reserved iterable:// handling so unknown paths are not forwarded to urlHandler.

🎟️ Jira Ticket: SDK-615

📖 Description

  • New IterableInboxMessageDisplay.test.tsx exercises WebView onMessage flows: https, iterable://delete / dismiss, action://, unknown iterable://, custom scheme → urlHandler, and trackInAppClick / trackInAppClose.
  • IterableInboxMessageDisplay returns early for any other iterable:// URL after delete/dismiss (SDK-633 alignment).
  • CHANGELOG.md Unreleased notes.

🧪 How to test?

  • yarn lint && yarn typecheck && yarn test --coverage && yarn check:circular && yarn prepare

🧾 Changelog

Unreleased entries in CHANGELOG.md (customer-facing fix + tests note).

🐞 Github Issues solved

N/A

Align reserved iterable:// handling so unknown schemes do not reach
urlHandler; only delete and dismiss run SDK actions.
@jferrao-itrbl
jferrao-itrbl requested a review from a team as a code owner November 6, 2026 14:05
@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Lines Statements Branches Functions
Coverage: 77%
77.98% (673/863) 67.48% (276/409) 72.99% (200/274)

@qltysh

qltysh Bot commented Nov 6, 2026

Copy link
Copy Markdown

Qlty


Coverage Impact

⬆️ Merging this pull request will increase total coverage on master by 4.2%.

Modified Files with Diff Coverage (1)

RatingFile% DiffUncovered Line #s
Coverage rating: F Coverage rating: A
src/inbox/components/IterableInboxMessageDisplay.tsx100.0%
Total100.0%
🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

Drop the file-local jest.mock so we use jest.setup’s View stub; find the
WebView node by View type + onMessage.
@jferrao-itrbl

Copy link
Copy Markdown
Collaborator Author

Product note — unknown iterable:// URLs and analytics (Q1)

The behavior where we still call trackInAppClick / trackInAppClose for unknown iterable:// paths (while skipping urlHandler and returnToInbox) matches native HTML in-app behavior:

  • Android: IterableInAppFragmentHTMLNotification.onUrlClicked records click/close before invoking the click callback that routes URLs and keeps unknown iterable:// off urlHandler / custom action handlers (IterableInAppManagerTest).
  • iOS: IterableHtmlMessageViewController records the click before onClickCallback, which leads to InAppManager.handleIterableCustomAction — unknown names return without routing (InAppManager.swift).

So the most consistent product answer is: keep click/close tracking for reserved-but-unknown iterable:// URLs unless Product explicitly wants RN inbox to diverge from native.

Comment why trackInAppClick/Close run before unknown iterable:// handling.

@rtlsilva rtlsilva left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes, plus one additional PR-level comment:

The body says "SDK-633 alignment", but this PR ships only SDK-633 item 3 (inbox parity). Suggest saying that SDK-633 stays open for:

  • the example: example/src/hooks/useIterableApp.tsx:197 still sets allowedProtocols = ['app', 'iterable'], and its urlHandler (lines 178–189) still treats these links as navigation. After this PR, example inbox links that use iterable:// stop navigating.
  • docs saying iterable:// is reserved for delete/dismiss (SDK-633 AC1). None exist yet.
  • SDK-633 AC3 and AC5.

Comment on lines +187 to +189
// iterable:// is reserved — only delete/dismiss are SDK actions (SDK-633)
} else if (URL.startsWith('iterable://')) {
return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This branch tracks a close but leaves the message open. Lines 169–179 already sent trackInAppClick and trackInAppClose(link), and return then keeps the message on screen. When the user taps Inbox, line 219 sends a second close (back) for the same view.

Native in-apps close the message after every link click, including an unknown iterable://. Only the action is skipped:

  • Android 3.10.1 IterableInAppFragmentHTMLNotification.onUrlClicked: click, close(LINK), then hideWebView().
  • iOS 6.7.5 IterableHtmlMessageViewController decidePolicyFor: trackClickOnDismiss, then animateWhileLeaving. close(link) is sent on disappear.

So "swallow, same as native" in SDK-633 means: close the message and call no handler.

Suggested change
// iterable:// is reserved — only delete/dismiss are SDK actions (SDK-633)
} else if (URL.startsWith('iterable://')) {
return;
// iterable:// is reserved: only delete/dismiss are SDK actions (SDK-633).
// Any other path closes the message without calling a handler, like native.
} else if (URL.startsWith('iterable://')) {
returnToInbox();

SDK-615 AC4 ("no navigation") should then read "no urlHandler or customActionHandler call".

Comment on lines +166 to +168
// Track before routing: aligns with native HTML in-app (click/close first,
// then iterable:// handling). Unknown iterable:// paths still get these
// events while skipping urlHandler / returnToInbox below.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment says unknown paths skip returnToInbox. Native closes the message (see the comment on line 189).

Suggested change
// Track before routing: aligns with native HTML in-app (click/close first,
// then iterable:// handling). Unknown iterable:// paths still get these
// events while skipping urlHandler / returnToInbox below.
// Track before routing, like native HTML in-apps: every link click sends
// click and close(link), then the message closes. Unknown iterable://
// paths close without calling urlHandler or customActionHandler.

Comment on lines +184 to +193
it('should swallow unknown iterable:// URLs without calling urlHandler or returning to inbox', async () => {
const utils = await renderWithContent();

postWebViewMessage(utils, 'iterable://foo');

expect(returnToInbox).not.toHaveBeenCalled();
expect(urlHandler).not.toHaveBeenCalled();
expect(MockLinking.openURL).not.toHaveBeenCalled();
expect(deleteRow).not.toHaveBeenCalled();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test locks in the open-message behaviour, and it never checks customActionHandler (SDK-633: "Do not forward unknown iterable:// to customActionHandler"). With the fix proposed in IterableInboxMessageDisplay.tsx's comments:

Suggested change
it('should swallow unknown iterable:// URLs without calling urlHandler or returning to inbox', async () => {
const utils = await renderWithContent();
postWebViewMessage(utils, 'iterable://foo');
expect(returnToInbox).not.toHaveBeenCalled();
expect(urlHandler).not.toHaveBeenCalled();
expect(MockLinking.openURL).not.toHaveBeenCalled();
expect(deleteRow).not.toHaveBeenCalled();
});
it('should close the message for unknown iterable:// URLs without calling any handler', async () => {
const utils = await renderWithContent();
const url = 'iterable://foo';
postWebViewMessage(utils, url);
expect(returnToInbox).toHaveBeenCalledTimes(1);
expect(trackInAppClickSpy).toHaveBeenCalledTimes(1);
expect(trackInAppCloseSpy).toHaveBeenCalledTimes(1);
expect(trackInAppCloseSpy).toHaveBeenCalledWith(
rowViewModel.inAppMessage,
IterableInAppLocation.inbox,
IterableInAppCloseSource.link,
url
);
expect(urlHandler).not.toHaveBeenCalled();
expect(customActionHandler).not.toHaveBeenCalled();
expect(MockLinking.openURL).not.toHaveBeenCalled();
expect(deleteRow).not.toHaveBeenCalled();
});


expect(returnToInbox).toHaveBeenCalled();
expect(deleteRow).not.toHaveBeenCalled();
expect(urlHandler).not.toHaveBeenCalled();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest adding expect(customActionHandler).not.toHaveBeenCalled(); here, and in the iterable://delete test (after line 151). As it is, a branch that forwarded reserved URLs to customActionHandler would pass all three reserved-URL tests.

Comment thread CHANGELOG.md

### Fixes

- Inbox message HTML links: unknown `iterable://` URLs no longer fall through to `urlHandler`; only `iterable://delete` and `iterable://dismiss` are handled as SDK actions (SDK-615, SDK-633).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes behaviour for anyone who used iterable://… links as deep links in inbox HTML. The bullet should tell them what to use instead. action://name is already documented on customActionHandler in IterableConfig.ts.

Suggested change
- Inbox message HTML links: unknown `iterable://` URLs no longer fall through to `urlHandler`; only `iterable://delete` and `iterable://dismiss` are handled as SDK actions (SDK-615, SDK-633).
- Fixed inbox HTML messages forwarding unknown `iterable://` links to `urlHandler`. `iterable://` is reserved for `iterable://delete` and `iterable://dismiss`; any other `iterable://` link now closes the message without calling a handler. Use `action://name` for custom actions (`customActionHandler`) and `https` or your app's own scheme for deep links (`urlHandler`).

Comment thread CHANGELOG.md

### Updates

- Added unit tests for inbox message link handling in `IterableInboxMessageDisplay` (SDK-615).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as in #937

Suggested change
- Added unit tests for inbox message link handling in `IterableInboxMessageDisplay` (SDK-615).

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants